package com.micro.modual.service.impl;

import com.micro.common.MicroConstant;
import com.micro.common.MicroResponseCode;
import com.micro.common.util.JacksonUtil;
import com.micro.core.handler.BaseContextHandler;
import com.micro.core.resp.RespJsonData;
import com.micro.modual.entity.SystemElement;
import com.micro.modual.entity.SystemMenu;
import com.micro.modual.entity.SystemUser;
import com.micro.modual.extension.SystemMenuExtension;
import com.micro.modual.mapper.SystemElementMapper;
import com.micro.modual.mapper.SystemMenuMapper;
import com.micro.modual.mapper.SystemUserMapper;
import com.micro.modual.model.dto.permission.FrontPermissionInfoDTO;
import com.micro.modual.model.dto.permission.FrontUserInfoDTO;
import com.micro.modual.model.tree.MenuTreeDTO;
import com.micro.modual.service.PermissionService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * @author LevelCoder
 * @version V1.0.0
 * @email LevelCoder@126.com
 * @date 2020/5/12
 */
@Slf4j
@Service("permissionService")
public class PermissionServiceImpl implements PermissionService {

    @Autowired
    private SystemUserMapper systemUserMapper;

    @Autowired
    private SystemMenuMapper systemMenuMapper;

    @Autowired
    private SystemElementMapper systemElementMapper;

    @Override
    public RespJsonData<FrontUserInfoDTO> getUserInfo() {
        String userCode = BaseContextHandler.getCustomerCode();
        SystemUser systemUser = systemUserMapper.findUserInfoByUserCode(userCode);
        //根据用户名获取当前用户所拥有的所有权限信息
        List<FrontPermissionInfoDTO> menuList = this.findPermissionInfoListWithMenu(userCode);
        List<FrontPermissionInfoDTO> elementList = this.findPermissionInfoListWithElement(userCode);
        FrontUserInfoDTO frontUserInfo = splicingFrontUserInfo(systemUser,menuList,elementList);
        return new RespJsonData<FrontUserInfoDTO>(frontUserInfo, MicroResponseCode.SUCCESS.getResponseCode(),MicroResponseCode.SUCCESS.getResponseMessage());

    }


    /**
     * <h2>根据用户编号获取当前用户所拥有的菜单权限信息</h2>
     * @param userCode 用户编号
     * @return {@link FrontPermissionInfoDTO}  前端授权路由对象 -> 菜单
     */
    private List<FrontPermissionInfoDTO> findPermissionInfoListWithMenu(String userCode) {
        List<SystemMenu> menuList = systemMenuMapper.findUserAuthorityMenuByUserCode(userCode);
        log.info("当前角色所拥有的菜单权限 userCode:{},menuList:{},menuListLenght:{}",BaseContextHandler.getCustomerCode(), JacksonUtil.toJson(menuList),menuList.size());
        return menuConversionPermission(menuList);
    }

    /**
     * <h2>菜单转权限</h2>
     * @param menuList {@link SystemMenu} s 菜单列表
     * @return {@link FrontPermissionInfoDTO}  前端授权路由对象 -> 菜单
     */
    private List<FrontPermissionInfoDTO> menuConversionPermission(List<SystemMenu> menuList) {
        List<FrontPermissionInfoDTO> frontPermissionInfoMenuList = new ArrayList<>();
        for(SystemMenu menu:menuList){
            FrontPermissionInfoDTO frontPermissionInfo = new FrontPermissionInfoDTO();
            frontPermissionInfo.setAuthCode(menu.getAuthCode());
            frontPermissionInfo.setMenuCode(menu.getMenuCode());
            frontPermissionInfo.setPermissionMethod(MicroConstant.SystemDefaultValue.DEFAULT_METHOD);
            frontPermissionInfo.setPermissionOperationName(MicroConstant.SystemDefaultValue.DEFAULT_OPERATION_NAME);
            frontPermissionInfo.setPermissionTitleName(menu.getMenuName());
            frontPermissionInfo.setPermissionType(menu.getMenuType());
            frontPermissionInfo.setPermissionUri(menu.getMenuUrl());
            frontPermissionInfoMenuList.add(frontPermissionInfo);
        }
        return frontPermissionInfoMenuList;
    }


    /**
     * <h2>根据用户编号获取当前用户所拥有的按钮权限信息</h2>
     * @param userCode 用户编号
     * @return  {@link FrontPermissionInfoDTO}  前端授权路由对象 -> 按钮
     */
    private List<FrontPermissionInfoDTO> findPermissionInfoListWithElement(String userCode) {
        List<SystemElement> elementList = systemElementMapper.findUserAuthorityElementByUserCode(userCode);
        return elementConversionPermission(elementList);
    }

    /**
     * <h2>按钮转权限</h2>
     * @param elementList {@link SystemElement} 按钮对象
     * @return {@link FrontPermissionInfoDTO}  前端授权路由对象 -> 按钮
     */
    private List<FrontPermissionInfoDTO> elementConversionPermission(List<SystemElement> elementList) {
        List<FrontPermissionInfoDTO> frontPermissionInfoElementList = new ArrayList<>();
        for(SystemElement element:elementList){
            FrontPermissionInfoDTO frontPermissionInfo = new FrontPermissionInfoDTO();
            frontPermissionInfo.setAuthCode(element.getAuthCode());
            frontPermissionInfo.setMenuCode(element.getMenuCode());
            frontPermissionInfo.setPermissionMethod(element.getElementMethod());
            frontPermissionInfo.setPermissionOperationName(element.getElementName());
            frontPermissionInfo.setPermissionType(element.getElementType());
            frontPermissionInfo.setPermissionUri(element.getElementUri());
            frontPermissionInfoElementList.add(frontPermissionInfo);
        }
        return frontPermissionInfoElementList;
    }


    /**
     * <h2>拼接前端用户信息</h2>
     * @param user           {@link SystemUser} 用户信息表
     * @param menuList       菜单列表
     * @param elementList    按钮列表
     * @return  {@link FrontUserInfoDTO} 前端用户信息返回对象
     */
    private FrontUserInfoDTO splicingFrontUserInfo(SystemUser user, List<FrontPermissionInfoDTO> menuList, List<FrontPermissionInfoDTO> elementList) {
        FrontUserInfoDTO frontUserInfo = new FrontUserInfoDTO();
        frontUserInfo.setUserName(user.getUserNickName());
        frontUserInfo.setUserCode(user.getUserCode());
        frontUserInfo.setUserPhone(user.getUserPhone());
        frontUserInfo.setUserStatus(String.valueOf(user.getUserStatus()));
        frontUserInfo.setUserAvatar(user.getUserAvatar());
        frontUserInfo.setMenuList(menuList);
        frontUserInfo.setElementList(elementList);
        return frontUserInfo;
    }

    /**
     * <h2>获取该用户拥有的菜单权限</h2>
     * @return {@link MenuTreeDTO} s 菜单树
     */
    @Override
    public RespJsonData<List<MenuTreeDTO>> getUserMenus() {
        String userCode = BaseContextHandler.getCustomerCode();
        List<SystemMenu> menuList = systemMenuMapper.findUserAuthorityMenuByUserCode(userCode);
        List<MenuTreeDTO> menuTreeList = SystemMenuExtension.buildMenuTree(menuList);
        return new RespJsonData<List<MenuTreeDTO>>(menuTreeList,MicroResponseCode.SUCCESS.getResponseCode(),MicroResponseCode.SUCCESS.getResponseMessage());
    }
}
